﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Windows;
using System.Windows.Data;

namespace Gmantis.Controls.Chart
{
    internal class DataBindingHelper
    {
        // Fields
        private static Type[] _supportedTypes = new Type[] { typeof(double), typeof(float), typeof(decimal), typeof(byte), typeof(short), typeof(int), typeof(long), typeof(ushort), typeof(uint), typeof(ulong), typeof(DateTime), typeof(Point) };

        // Methods
        public static void AutoCreateSeries(Chart chart, IEnumerable items)
        {
            if (chart.AutoGenerateSeries != false)
            {
                chart.Data.notify = false;
                List<DataSeries> list = new List<DataSeries>();
                foreach (DataSeries series in chart.Data.Children)
                {
                    if (series.AutoGenerated)
                    {
                        list.Add(series);
                    }
                }
                if (list.Count > 0)
                {
                    foreach (DataSeries series2 in list)
                    {
                        chart.Data.Children.Remove(series2);
                    }
                }
                if (chart.AutoGenerateSeries.HasValue || (chart.Data.Children.Count <= 0))
                {
                    ChartBindings bindings = chart.Bindings;
                    List<Binding> seriesBindings = null;
                    Binding xBinding = null;
                    if (bindings != null)
                    {
                        seriesBindings = bindings.SeriesBindings;
                        xBinding = bindings.XBinding;
                    }
                    Type itemType = GetItemType(items);
                    if (IsSupported(itemType))
                    {
                        DataSeries item = null;
                        if (itemType == typeof(Point))
                        {
                            XYDataSeries series4 = new XYDataSeries
                            {
                                AutoGenerated = true
                            };
                            Binding binding2 = new Binding
                            {
                                Path = new PropertyPath("X", new object[0])
                            };
                            series4.XValueBinding = binding2;
                            Binding binding3 = new Binding
                            {
                                Path = new PropertyPath("Y", new object[0])
                            };
                            series4.ValueBinding = binding3;
                            series4.FireNotifications = false;
                            item = series4;
                        }
                        else
                        {
                            item = new DataSeries
                            {
                                AutoGenerated = true,
                                FireNotifications = false
                            };
                            item.ValuesSource = items;
                        }
                        chart.Data.Children.Add(item);
                    }
                    else if ((seriesBindings != null) && (seriesBindings.Count > 0))
                    {
                        foreach (Binding binding4 in seriesBindings)
                        {
                            DataSeries series6 = null;
                            if (xBinding != null)
                            {
                                series6 = new XYDataSeries();
                            }
                            else
                            {
                                series6 = new DataSeries();
                            }
                            series6.AutoGenerated = true;
                            if ((binding4.Path != null) && !string.IsNullOrEmpty(binding4.Path.Path))
                            {
                                series6.Label = binding4.Path.Path;
                            }
                            series6.ValueBinding = binding4;
                            chart.Data.Children.Add(series6);
                        }
                    }
                    else if (itemType != null)
                    {
                        PropertyInfo[] properties = itemType.GetProperties();
                        if (properties != null)
                        {
                            if (xBinding != null)
                            {
                                int length = properties.Length;
                                for (int i = 0; i < length; i++)
                                {
                                    PropertyInfo info = properties[i];
                                    if ((info.Name != xBinding.Path.ToString()) && IsSupported(info.PropertyType))
                                    {
                                        XYDataSeries series7 = new XYDataSeries
                                        {
                                            AutoGenerated = true
                                        };
                                        series7.Label = info.Name;
                                        Binding binding5 = new Binding
                                        {
                                            Path = new PropertyPath(info.Name, new object[0])
                                        };
                                        series7.ValueBinding = binding5;
                                        chart.Data.Children.Add(series7);
                                    }
                                }
                            }
                            else if (chart.ChartType == ChartType.XYPlot)
                            {
                                XYPlotProcess(chart, properties);
                            }
                            else
                            {
                                DefaultProcess(chart, properties);
                            }
                        }
                    }
                    chart.Data.notify = true;
                }
            }
        }

        private static void DefaultProcess(Chart chart, PropertyInfo[] props)
        {
            int length = props.Length;
            for (int i = 0; i < length; i++)
            {
                PropertyInfo info = props[i];
                if (IsSupported(info.PropertyType))
                {
                    DataSeries item = new DataSeries
                    {
                        AutoGenerated = true
                    };
                    item.Label = info.Name;
                    Binding binding = new Binding
                    {
                        Path = new PropertyPath(info.Name, new object[0])
                    };
                    item.ValueBinding = binding;
                    chart.Data.Children.Add(item);
                }
            }
        }

        private static Type GetItemType(IEnumerable items)
        {
            IEnumerator enumerator = items.GetEnumerator();
            DataUtils.TryReset(enumerator);
            if (enumerator.MoveNext())
            {
                return enumerator.Current.GetType();
            }
            return null;
        }

        private static bool IsSupported(Type type)
        {
            int length = _supportedTypes.Length;
            for (int i = 0; i < length; i++)
            {
                if (_supportedTypes[i] == type)
                {
                    return true;
                }
            }
            return false;
        }

        private static void XYPlotProcess(Chart chart, PropertyInfo[] props)
        {
            int length = props.Length;
            XYDataSeries item = null;
            for (int i = 0; i < length; i++)
            {
                PropertyInfo info = props[i];
                if (IsSupported(info.PropertyType))
                {
                    if (item == null)
                    {
                        item = new XYDataSeries
                        {
                            AutoGenerated = true
                        };
                        item.Label = info.Name;
                        Binding binding = new Binding
                        {
                            Path = new PropertyPath(info.Name, new object[0])
                        };
                        item.XValueBinding = binding;
                    }
                    else
                    {
                        Binding binding2 = new Binding
                        {
                            Path = new PropertyPath(info.Name, new object[0])
                        };
                        item.ValueBinding = binding2;
                        chart.Data.Children.Add(item);
                        item = null;
                    }
                }
            }
            if ((item != null) && (item.ValueBinding == null))
            {
                item.ValueBinding = item.XValueBinding;
                item.XValueBinding = null;
                chart.Data.Children.Add(item);
            }
        }
    }
}
